﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WMS.Model;
using WMS.Repository.IRepository;
using WMS.Service.IService;

namespace WMS.Service
{
    public class RoleService : BaseServices<RoleModel>, IRoleService
    {
        private readonly IRoleRepository _roleRepository;
        private readonly IUserRepository _userRepository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly IRoleMenuRepository _roleMenuRepository;
        private readonly IMenuRepository _menuRepository;

        public RoleService(IBaseRepository<RoleModel> repository,
            ILogger<BaseServices<RoleModel>> logger,
            IRoleRepository roleRepository,
            IUserRepository userRepository,
            IUserRoleRepository userRoleRepository,
            IUnitOfWork unitOfWork,
            IRoleMenuRepository roleMenuRepository,
            IMenuRepository menuRepository) : base(repository, logger)
        {
            _roleRepository = roleRepository;
            _userRepository = userRepository;
            _userRoleRepository = userRoleRepository;
            _unitOfWork = unitOfWork;
            _roleMenuRepository = roleMenuRepository;
            _menuRepository = menuRepository;
        }

        /// <summary>
        /// 添加角色
        /// </summary>
        public async Task<(bool Success, string Message)> AddRoleAsync(string roleName, string roleDesc)
        {
            try
            {
                var role = await _roleRepository.GetRoleNameAsync(roleName);
                if (role != null)
                {
                    return (false, "角色已存在");
                }

                RoleModel model = new RoleModel()
                {
                    RoleName = roleName,
                    RoleDesc = roleDesc,
                    CreateTime = DateTime.Now,
                };

                bool result = await _repository.AddAsync(model);
                if (result)
                {
                    return (true, "添加成功！");
                }
                else
                {
                    return (false, "添加失败，请重新尝试！");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加角色失败 - 角色名称: {roleName}");
                throw;
            }
        }

        /// <summary>
        /// 分页查询角色列表
        /// </summary>
        public async Task<PageResult<RoleModel>> GetRolePagedListAsync(RoleQueryRequest request)
        {
            try
            {
                if (request.PageSize > 100)
                {
                    request.PageSize = 100;
                }
                return await _roleRepository.GetRolePagedListAsync(request);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "角色分页查询失败");
                throw;
            }
        }

        /// <summary>
        /// 修改角色
        /// </summary>
        public async Task<(bool Success, string Message)> UpdateRoleAsync(long id, string roleName, string roleDesc, byte status)
        {
            try
            {
                var role = await _repository.GetAsync(id);
                if (role == null)
                {
                    return (false, "角色不存在！");
                }

                role.RoleName = roleName;
                role.RoleDesc = roleDesc;
                role.UpdateTime = DateTime.Now;
                role.Status = status;

                bool result = await _repository.UpdateAsync(role);
                if (result)
                {
                    return (true, "修改成功！");
                }
                else
                {
                    return (false, "修改失败，请重新尝试！");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"修改角色失败 - 角色ID: {id}");
                throw;
            }
        }

        /// <summary>
        /// 启用禁用角色
        /// </summary>
        public async Task<(bool Success, string Message)> UpdateRoleStatusAsync(long id)
        {
            try
            {
                var role = await _repository.GetAsync(id);
                if (role == null)
                {
                    return (false, "角色不存在！");
                }

                role.Status = (byte)(role.Status == 0 ? 1 : 0);
                bool result = await _repository.UpdateAsync(role);
                if (result)
                {
                    return (true, "操作成功！");
                }
                else
                {
                    return (false, "操作失败，请重新尝试！");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新角色状态失败 - 角色ID: {id}");
                throw;
            }
        }

        /// <summary>
        /// 批量启用禁用角色
        /// </summary>
        public async Task<(bool Success, string Message)> UpdateRolesStatusAsync(List<long> ids)
        {
            try
            {
                var successCount = 0;
                var notFoundIds = new List<long>();
                var failedIds = new List<long>();

                foreach (var id in ids)
                {
                    try
                    {
                        var role = await _repository.GetAsync(id);
                        if (role == null)
                        {
                            notFoundIds.Add(id);
                            continue;
                        }

                        role.Status = (byte)(role.Status == 0 ? 1 : 0);
                        bool result = await _repository.UpdateAsync(role);
                        if (result)
                        {
                            successCount++;
                        }
                        else
                        {
                            failedIds.Add(id);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"处理角色状态失败 - 角色ID: {id}");
                        failedIds.Add(id);
                    }
                }

                var message = $"操作完成：成功 {successCount} 个，失败 {failedIds.Count} 个，未找到 {notFoundIds.Count} 个";
                return (successCount > 0, message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"批量更新角色状态失败 - 角色数量: {ids?.Count ?? 0}");
                throw;
            }
        }

        /// <summary>
        /// 获取用户角色穿梭数据
        /// </summary>
        public async Task<(bool Success, string Message, object Data)> GetUserRoleInfoAsync(long roleId)
        {
            try
            {
                var roleTask = _repository.GetAsync(roleId);
                var usersTask = _userRepository.QueryAsync();

                await Task.WhenAll(roleTask, usersTask);

                var role = await roleTask;
                if (role == null)
                    return (false, "角色不存在!", null);

                var allUsers = (await usersTask).Where(u => u.Status == 1).ToList();
                var bandUserIds = await _userRoleRepository.BandRoleUserListAsync(roleId);
                var bandUserIdSet = bandUserIds.Select(b => b.UserId).ToHashSet();

                var bandUserList = allUsers.Where(u => bandUserIdSet.Contains((long)u.Id)).ToList();
                var noBandUsers = allUsers.Where(u => !bandUserIdSet.Contains((long)u.Id)).ToList();

                var data = new
                {
                    noBandUsers,
                    bandUsers = bandUserList,
                };

                return (true, "查询成功", data);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户角色信息失败 - 角色ID: {roleId}");
                return (false, "系统错误，请稍后重试", null);
            }
        }

        /// <summary>
        /// 绑定/解绑用户
        /// </summary>
        public async Task<(bool Success, string Message)> IsBandUserAsync(int isBand, long roleId, List<long> userIds)
        {
            try
            {
                var operation = isBand == 1 ? "绑定" : "解绑";
                var errorMessage = $"{operation}用户角色失败";

                var result = await _unitOfWork.ExecuteTransactionAsync(async () =>
                {
                    foreach (var userId in userIds)
                    {
                        var model = new UserRoleModel
                        {
                            UserId = userId,
                            RoleId = roleId,
                        };

                        if (isBand == 1)
                            await _userRoleRepository.BandUserAsync(model);
                        else
                            await _userRoleRepository.UnBandUserAsync(model);
                    }
                }, errorMessage);

                if (!result.Success)
                {
                    return (false, result.Message);
                }

                var successMessage = isBand == 1 ? "绑定成功" : "解绑成功";
                return (true, successMessage);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"绑定/解绑用户失败 - 角色ID: {roleId}, 操作类型: {(isBand == 1 ? "绑定" : "解绑")}");
                return (false, $"{(isBand == 1 ? "绑定" : "解绑")}失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 解绑/绑定菜单
        /// </summary>
        public async Task<(bool Success, string Message)> IsBindMenuAsync(long roleId, List<long> menuIds)
        {
            try
            {
                var existingBindings = await _roleMenuRepository.GetRoleMenuById(roleId);
                var existingMenuIds = existingBindings.Select(rm => rm.MenuId).ToList();

                var menusToAdd = menuIds.Except(existingMenuIds).ToList();
                var menusToRemove = existingMenuIds.Except(menuIds).ToList();

                var result = await _unitOfWork.ExecuteTransactionAsync(async () =>
                {
                    if (menusToRemove.Any())
                    {
                        await _roleMenuRepository.DeleteRoleMenus(roleId, menusToRemove);
                    }

                    if (menusToAdd.Any())
                    {
                        var newBindings = menusToAdd.Select(menuId => new RoleMenuModel
                        {
                            RoleId = roleId,
                            MenuId = menuId,
                            CreateTime = DateTime.Now
                        }).ToList();

                        await _roleMenuRepository.AddRoleMenus(newBindings);
                    }
                }, "绑定/解绑菜单失败");

                if (!result.Success)
                {
                    return (false, result.Message);
                }

                var message = BuildSuccessMessage(menusToAdd.Count, menusToRemove.Count);
                return (true, message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"绑定/解绑菜单失败 - 角色ID: {roleId}");
                return (false, $"操作失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 绑定菜单统计返回值
        /// </summary>
        private string BuildSuccessMessage(int addCount, int removeCount)
        {
            if (addCount > 0 && removeCount > 0)
                return $"绑定成功：新增 {addCount} 个菜单，解绑 {removeCount} 个菜单";
            else if (addCount > 0)
                return $"绑定成功：新增 {addCount} 个菜单";
            else if (removeCount > 0)
                return $"解绑成功：移除 {removeCount} 个菜单";
            else
                return "无变化";
        }

        /// <summary>
        /// 获取菜单树（包含角色绑定状态）
        /// </summary>
        public async Task<List<MenuBandTreeDto>> GetMenuTreeWithRoleStatusAsync(long roleId)
        {
            try
            {
                var allMenus = await _menuRepository.GetQueryableList();
                var roleMenuIds = await _roleMenuRepository.GetRoleMenuIds(roleId);
                var menuTree = BuildMenuTree(allMenus, roleMenuIds, null);
                return menuTree;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取菜单树失败 - 角色ID: {roleId}");
                throw;
            }
        }

        /// <summary>
        /// 递归构建菜单树
        /// </summary>
        private List<MenuBandTreeDto> BuildMenuTree(List<MenuModel> allMenus, List<long> roleMenuIds, long? parentId)
        {
            return allMenus
                .Where(m => m.ParentMenuId == parentId)
                .Select(menu => new MenuBandTreeDto
                {
                    Id = menu.Id,
                    MenuName = menu.MenuName,
                    IsBand = roleMenuIds.Contains(menu.Id),
                    Children = BuildMenuTree(allMenus, roleMenuIds, menu.Id)
                })
                .OrderBy(m => allMenus.FirstOrDefault(x => x.Id == m.Id)?.SortIndex ?? 0)
                .ToList();
        }
    }
}